package de.bazinga.rotw.effects;

import java.util.Stack;

import com.jme.bounding.BoundingBox;
import com.jme.math.Ring;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.Controller;
import com.jme.scene.Node;
import com.jme.scene.state.BlendState;
import com.jme.scene.state.ZBufferState;
import com.jmex.effects.particles.ParticleFactory;
import com.jmex.effects.particles.ParticleSystem;
import com.jmex.game.state.GameStateManager;

import de.bazinga.rotw.game.Game;
import de.bazinga.rotw.game.RotwGameState;
import de.bazinga.rotw.objects.GameObject;
import de.bazinga.rotw.person.Person;
import de.bazinga.rotw.texture.TextureCache;

public class Explosion extends Node implements GameObject {
	private static final long serialVersionUID = 1L;


	private static Stack<Explosion> unusedExplosion = new Stack<Explosion>();
	
	private ParticleSystem explosionParticles = null;
	
	private long hideTime = 0;
	
	public Explosion(Vector3f location) {
		super("Explosion");
		this.setIsCollidable(false);
		
		// Smoke Granade Test
		explosionParticles = ParticleFactory.buildParticles("Explosion", 150);
		explosionParticles.setGeometry(new Ring(new Vector3f(0,0,0),
				new Vector3f(0,1f,0),
				0.1f,
				0.1f));
		explosionParticles.setEmissionDirection(new Vector3f(0,1,0f));
		
		
		
		float pi = 3.14159265f;
		explosionParticles.setMinimumAngle(0);
		explosionParticles.setMaximumAngle((pi)/2.0f);
		explosionParticles.setInitialVelocity(0.008f);
		explosionParticles.setMinimumLifeTime(600.0f);
		explosionParticles.setMaximumLifeTime(800.0f);
		explosionParticles.setStartSize(0.008f);
		explosionParticles.setEndSize(2f);
		explosionParticles.setStartColor(ColorRGBA.darkGray);
		explosionParticles.setEndColor(ColorRGBA.gray);
		explosionParticles.getParticleController().setControlFlow(false);
		explosionParticles.getParticleController().setRepeatType(
                Controller.RT_CLAMP);
        

		explosionParticles.setIsCollidable(false);
        
		
		BlendState bs = Game.getGame().getDisplay().getRenderer().createBlendState();
        bs.setBlendEnabled(true);
        bs.setSourceFunction(BlendState.SourceFunction.SourceAlpha);
        bs.setDestinationFunction(BlendState.DestinationFunction.SourceAlpha);
        bs.setTestEnabled(true);
        explosionParticles.setRenderState(bs);
        
        explosionParticles.setRenderState(
				TextureCache.getInstance().getTexture("texture/fire.png"));
		
		
        explosionParticles.setModelBound(new BoundingBox());
		explosionParticles.updateModelBound();
		
		
		ZBufferState zs = Game.getGame().getDisplay().getRenderer().createZBufferState();
	    zs.setWritable(false);
	    explosionParticles.setRenderState(zs);
	    explosionParticles.updateRenderState();
		this.attachChild(explosionParticles);
		
		this.setLocalTranslation(location);
		this.updateGeometricState(0, false);
	}
	
	
	public void reset(Vector3f location) {
		this.setLocalTranslation(location);
		this.updateGeometricState(0, false);
		explosionParticles.forceRespawn();
		explosionParticles.getParticleController().setRepeatType(Controller.RT_CLAMP);
	}
	
	
	public void hide() {
		hideTime = System.currentTimeMillis();
		((RotwGameState)GameStateManager.getInstance().getChild("gameState")).addItemToRespawn(this);
	}

	public boolean respawn() {
		if( (System.currentTimeMillis() - hideTime) > 3000) {
			explosionParticles.getParticleController().setRepeatType(Controller.RT_CLAMP);
			
			addUnusedExplosion(this);
			
			return true;
		}
		return false;
	}
	
	
	public void onCollision(Person person, boolean sendMessage) {}


	public ParticleSystem getExplosionParticles() {
		return explosionParticles;
	}
	
	public static synchronized void addUnusedExplosion(Explosion s) {
		unusedExplosion.push(s);
	}

	public static synchronized Explosion getUnusedExplosion(Vector3f location) {
		if(unusedExplosion.size() == 0) {
			return new Explosion(location);
		}
		Explosion s = unusedExplosion.pop();
		s.reset(location);
		return s;
	}
}